<template>
  <main-card :crumbs="crumbs" :loading="loading" :main-body-style-obj="mainBodyStyleObj" :screen-style-obj="{ padding: 0 }">
    <div class="mt-12 algo-test-edit">
      <div class="tools">
        <div class="task-status" :class="[statusObj.className]">
          <div class="icon-box fc">
            <i class="iconfont" :class="[statusObj.iconName]"></i>
          </div>
          <div class="text fc">{{ statusObj.name }}</div>
        </div>
        <div class="ml-20 task-info">
          <div class="mt-4">
            <div class="label">任务名称</div>
            <div class="ml-24 value" :title="pageForm.taskName">{{ pageForm.taskName }}</div>
          </div>
          <div>
            <div class="label">测试指标</div>
            <div class="ml-24 value" :title="normsTitle()">
              <span v-for="(norms, index) in pageForm.taskNormDetails" :key="index" class="value__item">{{ norms.name }}</span>
            </div>
          </div>
        </div>
        <div class="ml-20 task-info">
          <div class="mt-4">
            <div class="label" style="width: 84px">创建时间</div>
            <div class="ml-24 value" :title="pageForm.createTime">{{ pageForm.createTime }}</div>
          </div>
          <div class="mt-4">
            <div class="label" style="width: 84px">运行起止时间</div>
            <div class="ml-24 value" :title="spliceTwoTimes(pageForm.startTime!, pageForm.endTime!)">
              {{ spliceTwoTimes(pageForm.startTime!, pageForm.endTime!) }}
            </div>
            <div class="label">操作者</div>
            <div class="ml-24 value max-w-100" style="min-width: 0" :title="pageForm.username">{{ pageForm.username }}</div>
          </div>
        </div>
        <div class="flex-1"></div>
        <div class="btn-list">
          <i v-if="canDownload" class="ml-20 cursor-pointer icon-download-2-line iconfont" @click="downloadTaskRecord(pageForm.id!)"></i>
        </div>
      </div>
      <div ref="mainRef" class="main">
        <left-collapse ref="leftCollapseRef" class="left-collapse my-scrollbar" :status="pageForm.status" @updateCode="updateCode" />
        <div ref="codeAndResRef" class="code-and-res">
          <code-editor ref="codeEditorRef" class="code-editor" :style="{ height: `calc(100% - ${showRes ? resBoxHeight : 0}px)` }" />
          <transition>
            <div v-if="showRes" class="res-box" :style="{ height: resBoxHeight + 'px' }">
              <div ref="resizeBoxRef" class="resize-handle fc">
                <svg width="18" height="3" viewBox="0 0 18 3" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <circle cx="2" cy="1.5" r="1.5" fill="white" />
                  <circle cx="9" cy="1.5" r="1.5" fill="white" />
                  <circle cx="16" cy="1.5" r="1.5" fill="white" />
                </svg>
              </div>
              <div class="res-title no-select">运行结果</div>
              <div v-if="pageForm.status === 2" class="res-body fc running">
                <a-spin />
                代码运行中，请等待...
              </div>
              <div v-else class="res-body my-scrollbar">
                <pre>{{ pageForm.runResult }}</pre>
              </div>
            </div>
          </transition>
        </div>
      </div>
    </div>
  </main-card>
</template>

<script lang="ts" setup>
  import { useDraggable, useElementSize } from '@vueuse/core'
  import { computed, nextTick, ref, watch } from 'vue'
  import { useRequest } from 'vue-request'
  import { useRoute } from 'vue-router'

  import CodeEditor from '@/components/CodeEditor/index.vue'
  import MainCard, { Crumb } from '@/components/MainCard/index.vue'
  import { algoTestApi } from '@/services'
  import { getDistanceFromTop, spliceTwoTimes } from '@/utils'

  import { TaskDetail } from '../types'
  import { downloadTaskRecord } from '../utils'
  import LeftCollapse from './components/LeftCollapse.vue'

  const route = useRoute()
  const recordId = route.params.id as string

  const {
    data: taskDetailRes,
    loading: taskDetailLoading,
    runAsync: getTaskDetailRun
  } = useRequest<ResponseData<TaskDetail>>(algoTestApi.recordDetail(recordId))

  const mainBodyStyleObj = ref({
    padding: '0'
  })

  const leftCollapseRef = ref()
  const codeEditorRef = ref<InstanceType<typeof CodeEditor>>()
  const pageForm = ref<TaskDetail>({
    taskId: '',
    createTime: '',
    taskNormDetails: [],
    status: 0,
    taskName: '',
    username: '',
    bucketList: [],
    modelList: [],
    dataIds: [],
    modelIds: [],
    codeTree: { childList: [] },
    mainPath: '',
    url: '',
    id: '',
    startTime: '',
    endTime: '',
    runResult: ''
  })
  const showRes = computed(() => [3, 4, 5, 6].includes(pageForm.value.status))
  const canDownload = computed(() => [3, 4, 5].includes(pageForm.value.status))
  const taskStatus = [
    {
      status: 0,
      name: '未运行',
      iconName: 'icon-play-fill',
      className: ''
    },
    {
      status: 1,
      name: '待运行',
      iconName: 'icon-play-fill',
      className: 'wait'
    },
    {
      status: 2,
      name: '运行中',
      iconName: 'icon-play-fill',
      className: 'running'
    },
    {
      status: 3,
      name: '成功',
      iconName: 'icon-check-double-line',
      className: 'success'
    },
    {
      status: 4,
      name: '失败',
      iconName: 'icon-close-circle-fill',
      className: 'error'
    },
    {
      status: 5,
      name: '超时',
      iconName: 'icon-time-fill',
      className: 'error'
    },
    {
      status: 6,
      name: '准备中',
      iconName: 'icon-play-fill',
      className: ''
    }
  ]
  const statusObj = computed(() => taskStatus[pageForm.value.status] ?? {})
  const crumbs = computed<Crumb[]>(() => [
    {
      name: '算法测试',
      path: '/algo-test/task-list'
    },
    {
      name: `运行记录（${pageForm.value.taskName}）`,
      path: `/algo-test/record-list/${pageForm.value.taskId}?name=${pageForm.value.taskName}`
    },
    {
      name: `运行详情（${pageForm.value.taskName}）`
    }
  ])

  const getTaskDetail = async () => {
    await getTaskDetailRun()
    const data = taskDetailRes.value?.data as TaskDetail
    Object.assign(pageForm.value, data)

    // 对数据集进行处理
    data.buckets?.forEach((it: any) => {
      pageForm.value.bucketList.push({
        key: it.dataId,
        title: it.fileName,
        isLeaf: it.fileType === 1,
        checked: true,
        deleted: it.deleted
      })
      pageForm.value.dataIds.push(it.dataId)
    })
    // 对模型进行处理
    data.models?.forEach((it: any) => {
      pageForm.value.modelList.push({
        key: it.modelId,
        title: it.modelName,
        isLeaf: it.fileType === 1,
        checked: true,
        deleted: it.deleted
      })
      pageForm.value.modelIds.push(it.dataId)
    })

    nextTick(() => {
      codeEditorRef.value?.setReadOnly(true)
      const data = pageForm.value
      // 有主文件路径则说明已经运行过，需给左侧数据赋值

      leftCollapseRef.value.updateCheckedDataBucketList(data.bucketList, data.dataIds)
      leftCollapseRef.value.updateCheckedModelList(data.modelList, data.modelIds)
      leftCollapseRef.value.setCodeTreeAndSource(data.url, data.codeTree.childList, [data.mainPath])

      getCodeAndResHeight()
    })
  }

  const updateCode = (str: string) => {
    codeEditorRef.value?.setValue(str)
  }

  const loading = computed(() => {
    if (!leftCollapseRef.value) {
      return true
    }
    return leftCollapseRef.value.pageLoading || taskDetailLoading.value
  })

  const normsTitle = () => {
    if (pageForm.value.taskNormDetails) {
      const nameList = pageForm.value.taskNormDetails.map(taskDetail => {
        return taskDetail.name
      })
      return nameList.join('|')
    }
    return ''
  }

  /* 拖拽改变大小逻辑 ------------------------------------------------ */
  const mainRef = ref<HTMLElement>()
  const resizeBoxRef = ref<HTMLElement>()
  const resBoxHeight = ref(460)
  const codeAndResRef = ref<HTMLElement>()

  const resizeHandler = (mousePosition: any) => {
    console.log(mousePosition.y)
    console.dir(mainRef.value)
    // 编辑器高度 = 鼠标当前位置 - main.offsetTop
    let editorHeight = mousePosition.y - getDistanceFromTop(mainRef.value)
    editorHeight = editorHeight > 100 ? editorHeight : 100

    let newHeight = mainRef.value!.offsetHeight - editorHeight
    newHeight = newHeight > 100 ? newHeight : 100

    resBoxHeight.value = newHeight
  }

  // 头部定位距离计算
  useDraggable(resizeBoxRef, { onMove: resizeHandler })
  const { width: mainWidth } = useElementSize(mainRef)

  watch(mainWidth, width => {
    codeEditorRef.value?.setEditorSize({ width: width - 326 })
  })
  // 在页面初始化时获取容器的高度并将高度的一半传递给resBoxHeight.value
  const getCodeAndResHeight = () => {
    console.log(codeAndResRef.value?.clientHeight)
    if (codeAndResRef.value?.clientHeight) {
      resBoxHeight.value = codeAndResRef.value?.clientHeight / 2
    }
  }

  /*  ------------------------------------------------------------------- */

  getTaskDetail()
</script>

<style lang="less" scoped>
  @import '@/styles/mixins.less';

  .algo-test-edit {
    display: flex;
    flex-direction: column;
    border-top: 1px solid @border2;

    .header {
      display: flex;
      height: 44px;
      border-bottom: 1px solid @border2;

      .logo {
        width: 60px;
        height: 44px;
        border-right: 1px solid @border2;
      }

      .crumbs {
        padding-left: 10px;

        .task-name {
          color: @text01;
          .font16b();
        }
      }
    }

    .tools {
      display: flex;
      align-items: center;
      padding: 20px 24px;
      border-bottom: 1px solid @border2;

      .task-status {
        // overflow: hidden;
        border-radius: 2px;

        .icon-box {
          width: 56px;
          height: 40px;
          background: rgba(25, 25, 48, 0.045);

          .iconfont {
            font-size: 24px;
            color: #505062;
          }
        }

        .text {
          font-family: 'Noto Sans SC';
          color: #fff;
          background-color: @text03;
          font-style: normal;
          font-weight: 400;
          line-height: 22px;
          .font12();
        }

        &.wait {
          .icon-box {
            background-color: rgba(70, 134, 237, 0.1);

            .iconfont {
              color: rgba(70, 134, 237, 1);
            }
          }

          .text {
            background-color: rgba(70, 134, 237, 1);
          }
        }

        &.running {
          .icon-box {
            background-color: rgba(13, 76, 202, 0.1);

            .iconfont {
              color: rgba(13, 76, 202, 1);
            }
          }

          .text {
            background-color: rgba(13, 76, 202, 1);
          }
        }

        &.success {
          .icon-box {
            background-color: rgba(92, 201, 105, 0.1);

            .iconfont {
              color: rgba(92, 201, 105, 1);
            }
          }

          .text {
            background-color: rgba(92, 201, 105, 1);
          }
        }

        &.error {
          .icon-box {
            background-color: rgba(214, 24, 96, 0.1);

            .iconfont {
              color: rgba(214, 24, 96, 1);
            }
          }

          .text {
            background-color: rgba(214, 24, 96, 1);
          }
        }
      }

      .task-info {
        .font14();

        & > div {
          display: flex;
        }

        .label {
          color: @text02;
          .elliptical-1();
        }

        .value {
          // display: flex;
          width: 400px;
          color: @text01;
          .elliptical-1();

          .value__item + .value__item {
            position: relative;
            margin-left: 16px;

            &::before {
              position: absolute;
              content: '';
              top: 50%;
              transform: translateY(-50%);
              left: -8px;
              width: 1px;
              height: 12px;
              background: @border2;
            }
          }
        }
      }
    }

    .main {
      display: flex;
      overflow: hidden;
      max-width: 100%;
      height: 0;
      height: calc(100vh - 102px - 44px - 108px);
      min-height: 500px;

      .left-collapse {
        overflow: hidden;
        width: 326px;
        min-width: 326px;
        height: 100%;
      }

      .code-and-res {
        flex: 1;
        height: 100%;

        .code-editor {
          height: 100%;
        }

        .res-box {
          display: flex;
          width: 100%;
          background-color: @background2;
          flex-direction: column;

          .resize-handle {
            display: none;
            width: 100%;
            height: 7px;
            background: #ccc;
            cursor: ns-resize;
            transition: all 0.1s;

            &:active {
              background: @primary3;
            }
          }

          .res-title {
            display: flex;
            align-items: center;
            padding: 8px 16px;
            margin-top: 18px;
            height: 38px;
            color: @text01;
            background-color: @background3;
            border-style: solid;
            border-width: 1px 0;
            border-color: #d9d9db;
          }

          .res-body {
            overflow: auto;
            padding: 18px;
            flex: 1;
            flex-direction: column;

            pre {
              line-height: 1.5;
              white-space: pre-wrap;
              white-space: -moz-pre-wrap;
              white-space: -pre-wrap;
              white-space: -o-pre-wrap;
              word-wrap: break-word;
            }
          }
        }
      }
    }
  }
</style>
